package com.example.demo_yunpan.service.impl;

import com.example.demo_yunpan.entity.folder;
import com.example.demo_yunpan.entity.recycle;
import com.example.demo_yunpan.mapper.FolderMapper;
import com.example.demo_yunpan.mapper.RecycleMapper;
import com.example.demo_yunpan.service.FolderService;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileAlreadyExistsException;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

@Service
public class FolderServiceImpl implements FolderService {
    @Autowired
    private FolderMapper folderMapper;

    private final Configuration configuration = new Configuration();

    // 加载Hadoop配置文件
    public FolderServiceImpl() throws IOException {
        // 加载Hadoop配置文件
        configuration.addResource("core-site.xml");
        configuration.addResource("hdfs-site.xml");
    }

    FileSystem fs = FileSystem.get(configuration);

    /**
     * 根据userId查询第一级文件夹
     *
     * @Param userId
     * return list
     */
    @Override
    public List<folder> findFolderByuserId(String userId,String path) {
        return folderMapper.selectFolderByuserId(userId,path);
    }

    /**
     * 查询同一个用户Id的所有文件夹
     * @param userId,fileNameFuzzy,category
     * return List<folder>
     * */
    @Override
    public List<folder> findAllByuserId(String userId,String fileNameFuzzy,String category){
        return folderMapper.selectAllByuserId(userId,fileNameFuzzy,category);
    }

    /**
     * folderId查询文件夹
     *
     * @param folderId return 查询结果
     */
    public FileStatus selectFolderByFolderId(String folderId) throws IOException {
        folder f = folderMapper.selectFolderByFolderId(folderId);
        Path path = new Path(f.getHdfsPath());
        FileStatus fileStatus = fs.getFileStatus(path);
        fs.close();
        return fileStatus;
    }

    /**
     * 返回上一级文件夹
     * @param folderId
     * return 查询结果
     */
    @Override
    public folder getParentFolderById(String folderId) {
        return folderMapper.selectLastFolderByFolderId(folderId);
    }

    /**
     * 新建文件夹
     * @param folder1
     * return 插入结果
     */
    @Override
    public boolean createFolder(folder folder1) throws Exception {

        //查询同一级下的文件夹是否存在重复的文件夹名
        String baseName = folder1.getFolderName();
        folder folder2 = folderMapper.selecFolderByName(folder1.getLastFolder(),baseName);

        //如果同名且在同一层级
        if ((folder2!=null) && (folder2.getFolderName().equals(folder1.getFolderName())) && (folder2.getLastFolder() == folder1.getLastFolder())) {
            baseName = "新建文件夹";
            //如果还是重复，则修改文件夹名称为“新建文件夹1”、“新建文件夹2”等等
            folder2 = folderMapper.selecFolderByName(folder1.getLastFolder(),baseName);
            folder1.setFolderName(baseName);
            if ((folder2!=null)&&baseName.equals(folder2.getFolderName())){
                int suffix = 1;
                boolean flag = true;
                while (flag) {
                    // 修改文件夹名称为“新建文件夹1”、“新建文件夹2”等等
                    String newName = baseName + suffix;
                    folder1.setFolderName(newName);
                    folder2 = folderMapper.selecFolderByName(folder1.getLastFolder(),newName);
                    if ((folder2==null)) {
                        folder1.setFolderName(newName);
                        flag = false;
                    } else {
                        suffix++;
                    }
                }
            }
            //不重名,则创建新的文件夹
            //创建HDFS路径
            Path path = new Path(folder1.getParentHdfs() + "/" + folder1.getFolderName());
            System.out.println(path);
            folder1.setHdfsPath(String.valueOf(path));
            // 检查文件夹是否已存在
            if (fs.exists(path)) {
                //throw new Exception("Folder already exists in HDFS.");
                return false;
            }
            try {
                // 在HDFS上创建文件夹
                if (!fs.mkdirs(path)) {
                    //throw new Exception("Failed to create folder in HDFS.");
                    return false;
                }
            } catch (FileAlreadyExistsException e) {
                throw new Exception("文件夹已经存在", e);
            }

            // 获取当前创建时间（LocalDateTime）
            LocalDateTime now = LocalDateTime.now();
            // 将LocalDateTime转换为Instant（时区敏感）
            java.time.Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
            // 将Instant转换为Timestamp
            Timestamp timestamp = Timestamp.from(instant);
            folder1.setCreateTime(timestamp);
            //插入数据库
            return folderMapper.insertNewFolder(folder1);

        }
        return false;
    }

    /**
     * 删除文件夹
     * @param folderId
     */
    public boolean deleteFolder(String folderId) throws Exception {
        folder f = folderMapper.selecFolderById(folderId);
        Path hdfsPath = new Path(f.getHdfsPath());
        try {
            // 检查HDFS上文件夹是否存在
            if (fs.exists(hdfsPath)) {
                // 删除HDFS上的文件夹
                if (!fs.delete(hdfsPath, true)) {
                    throw new Exception("Failed to delete folder from HDFS.");
                }
            } else {
                throw new Exception("Folder does not exist in HDFS.");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Error deleting folder from HDFS: " + e.getMessage());
        }

        //将文件夹信息加入回收站表
        recycle r = new recycle();
        r.setItemId(f.getFolderId());
        r.setItemType(String.valueOf(0));
        r.setItemSize(f.getFolderSize());
        Instant now = Instant.now();
        Timestamp currentTimestamp = Timestamp.from(now);
        r.setDeleteTime(currentTimestamp);
        r.setHdfsPath(f.getHdfsPath());
        r.setUserId(f.getUserId());
        //recycleMapper.insertRecycle(r);

        //删除数据库folder表中文件夹信息
        if (f != null) {
            folderMapper.delectFolderByFolderId(String.valueOf(f.getFolderId()));
        } else {
            throw new Exception("Folder does not exist in the database.");
        }
        return true;
    }

    /**
     * 重命名文件夹
     *
     * @param oldName,newName
     */
    @Override
    public folder renameFolder(String oldName, String newName, String folderId) throws Exception {
        Path oldHdfsPath = new Path(oldName);
        Path newHdfsPath = new Path(newName);
        try {
            // 检查HDFS上旧文件夹是否存在
            if (fs.exists(oldHdfsPath)) {
                // 重命名HDFS上的文件夹
                if (!fs.rename(oldHdfsPath, newHdfsPath)) {
                    throw new Exception("Failed to rename folder in HDFS.");
                }
            } else {
                throw new Exception("Folder does not exist in HDFS.");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Error renaming folder in HDFS: " + e.getMessage());
        }

        // 从数据库中获取旧文件夹记录
        folder f = folderMapper.selecFolderById(folderId);
        if (f != null) {
            // 更新文件夹名称
            f.setFolderName(newName);
            f.setHdfsPath(newHdfsPath.toString());
            folderMapper.updataFolderInfo(f);
            return folderMapper.selecFolderById(folderId);
        } else {
            throw new Exception("Folder does not exist in the database.");
        }
    }

    /**
     * 移动文件夹
     *
     * @param folderId,lastFolder
     */
    @Override
    public folder moveFolder(String folderId, String lastFolder) throws Exception {
        folder f = folderMapper.selecFolderById(folderId);
        if (f != null) {
            folder newLastFolder = folderMapper.selecFolderById(lastFolder);
            if (newLastFolder != null) {

                // 更新文件夹的父文件夹ID
                f.setLastFolder(newLastFolder.getFolderId());

                // 更新文件夹的HDFS路径
                Path newHdfsPath = new Path(newLastFolder.getHdfsPath(), f.getFolderName());
                f.setHdfsPath(newHdfsPath.toString());

                //更新数据库
                folderMapper.updataFolderInfo(f);

            } else {
                throw new Exception("lastFolder does not exist in the database.");
            }
        } else {
            throw new Exception("Folder does not exist in the database.");
        }
        return f;
    }
}